package com.cn.tianxin.ssserver.ext;

import com.cn.tianxin.ssserver.utils.HttpUtil;
import com.cn.tianxin.ssserver.utils.PropUtil;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * 管理微信 acces_token类
 */
public class WXXCXAccessToken {
    private String access_token;
    private int expires_in;
    private Date tokenBeginTime;    //token获取的时间

    private static WXXCXAccessToken accessToken;    //全局持有1个token

    @Override
    public String toString() {
        return "WXAccessToken{" +
                "access_token='" + access_token + '\'' +
                ", expires_in=" + expires_in +
                ", tokenBeginTime=" + tokenBeginTime +
                '}';
    }

    private WXXCXAccessToken(String access_token, int expires_in) {
        this.access_token = access_token;
        this.expires_in = expires_in;
        this.tokenBeginTime = new Date();
    }

    private static final String DEFAULT_ENCODE = "UTF-8";

    public static String mapToURLStr(Map<String,String> param){

        StringBuilder stringBuilder = new StringBuilder();
        Set<Map.Entry<String, String>> entries = param.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, String> next = iterator.next();
            String paramStr = "";
            try {
                if (iterator.hasNext()){
                    paramStr = next.getKey() + "=" + URLEncoder.encode(next.getValue(), DEFAULT_ENCODE)+"&";
                }else {
                    paramStr = next.getKey() + "=" + URLEncoder.encode(next.getValue(), DEFAULT_ENCODE);
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();    //impossible
            }
            stringBuilder.append(paramStr);
        }

        return stringBuilder.toString();
    }


    public static WXXCXAccessToken getToken(){
        //http 请求获取
        if (WXXCXAccessToken.accessToken != null && !WXXCXAccessToken.accessToken.isExpired()){
            return WXXCXAccessToken.accessToken;
        }

        // httpclient 获取微信的access_token
        PropUtil propUtil = null;
        try {
            propUtil = PropUtil.getPropUtilFromMap("weixin.properties");
            String urlStr = "https://api.weixin.qq.com/cgi-bin/token";


            Map<String,Object> params = new HashMap<>();
            params.put("grant_type","client_credential");
            params.put("appid",propUtil.get("xcx_appid"));
            params.put("secret",propUtil.get("xcx_secret"));
            byte[] bytes = HttpUtil.httpRequest(urlStr, params, "GET");
            String resStr = new String(bytes,DEFAULT_ENCODE);

            ObjectMapper mapper = new ObjectMapper();
            Map map = mapper.readValue(resStr, Map.class);
            System.out.println("WXXCXAccessToken.getToken=>resMap=>"+map);

            if (map!=null && map.get("access_token")!=null){
                WXXCXAccessToken.accessToken = new WXXCXAccessToken(String.format("%s",map.get("access_token")), (Integer) map.get("expires_in"));
            }else {
                System.out.println("WXAccessToken.getToken=>"+map);
                WXXCXAccessToken.accessToken = null;
            }

        } catch (IOException e) {
            e.printStackTrace();
            WXXCXAccessToken.accessToken = null;
        }

        return WXXCXAccessToken.accessToken;

    }

    public String getAccess_token() {
        return access_token;
    }

    //判断token是否过期    过期返回true,否则返回true
    private boolean isExpired(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(this.tokenBeginTime);
        calendar.add(Calendar.SECOND,this.expires_in-30);    //提前三十秒认为过期，重新获取token
        //calendar.add(Calendar.SECOND,this.expires_in-7190);    //used for test

        return new Date().after(calendar.getTime());
    }

    public static void main(String[] args) throws InterruptedException {
        WXXCXAccessToken token = WXXCXAccessToken.getToken();
        if (token!=null){
            System.out.println("token.getAccess_token()=>"+token);
            System.out.println("token.isExpired()=>"+token.isExpired());
        }

        WXXCXAccessToken token2 = WXXCXAccessToken.getToken();
        if (token2!=null){
            System.out.println("token.getAccess_token()=>"+token2);
            System.out.println("token.isExpired()=>"+token2.isExpired());
        }

        Thread.sleep(9*1000);
        WXXCXAccessToken token3 = WXXCXAccessToken.getToken();
        if (token3!=null){
            System.out.println("token.getAccess_token()=>"+token3);
            System.out.println("token.isExpired()=>"+token3.isExpired());
        }

        Thread.sleep(10*1000);
        WXXCXAccessToken token4 = WXXCXAccessToken.getToken();
        if (token4!=null){
            System.out.println("token.getAccess_token()=>"+token4);
            System.out.println("token.isExpired()=>"+token4.isExpired());
        }

        Thread.sleep(11*1000);
        WXXCXAccessToken token5 = WXXCXAccessToken.getToken();
        if (token5!=null){
            System.out.println("token.getAccess_token()=>"+token5);
            System.out.println("token.isExpired()=>"+token5.isExpired());
        }

        //test ok
    }

}
